package com.bdh.javaBasicStudy;

import com.bdh.javaBasicStudy.EmployeeClass.Employee;
import com.bdh.javaBasicStudy.EmployeeClass.EmployeeData;
import org.junit.Test;

import javax.jnlp.ClipboardService;
import javax.lang.model.type.ArrayType;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @projectName: maven_project
 * @package: com.bdh.javaBasicStudy
 * @className: Java8NewProperties
 * @author: Dream
 * @description:
 * @date: 2022/6/18 13:48
 */
public class Java8NewProperties {
    /**
     * @param :
     * @return void
     * @author dreamyouth
     * @description Lambda使用
     * @date 2022/6/18 19:25
     */
    @Test
    public void  test1() {
        Runnable runnable = new Runnable() {
            public void run() {
                System.out.println("我爱北大荒");
            }
        };
        runnable.run();

        System.out.println("*****");
        Runnable runnable1 = () -> System.out.println("我爱哈尔滨");
        runnable1.run();
    }

    @Test
    public void test2(){
        Comparator<Integer> com1 = new Comparator<Integer>(){
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1, o2);
            }
        };

        int compare1 = com1.compare(12, 21);
        System.out.println(compare1);
        System.out.println("**************");

        Comparator<Integer> com2 = (o1, o2) -> Integer.compare(o1, o2);
        int compare2 = com2.compare(21, 24);
        System.out.println(compare2);

        System.out.println("*******");
        Comparator<Integer> com3 = Integer::compare;
        int compare3 = com3.compare(31, 56);
        System.out.println(compare3);
    }

    @Test
    public void test3(){
        //语法格式一：无参、无返回值
        Runnable r2 = () -> {System.out.println("Dreamyouth");};
        //语法格式二：Lambda 需要一个参数，但是没有返回值
        Consumer<String> con1 = (String s) -> {System.out.println(s);};
    //语法格式三: 数据类型可以省略，因为可由编译器推断得出，称为“类型推断”
        Consumer<String> con2 = (s) -> {System.out.println(s);};
    //语法格式四: 只需要一个参数的时候，参数的小括号可以省略
        Consumer<String> con3 = s -> {System.out.println(s);};
    //语法格式五: 需要两个或以上的参数，多条执行语句，并且可以有返回值
        Comparator<Integer> com2 = (o1, o2) -> {
            System.out.println(o1);
            System.out.println(o2);
            return o1.compareTo(o2);
        };
    //语法格式六: 当Lambda体只有一条语句时，return与大括号若有，都可以忽略
        Comparator<Integer> com3 = (o1, o2) -> o1.compareTo(o2);
        Consumer<String> con4 = (String s) -> {
            System.out.println(s);
        };
        con1.accept("cool");
    }

    /**
     * @description StremAPI
     */
    //创建方式
    @Test
    public void testStreamAPI(){
        //通过集合的方式来创建
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<Employee> stream = employees.stream();
        Stream<Employee> employeeStream = employees.parallelStream();

        //通过数组的方式
        int[] arr = new int[]{1,2,3,4,5,6};
        //调用Arrays类的static <T> Stream<T> stream(T[] array); 返回一个流
        IntStream stream1 = Arrays.stream(arr);

        Employee e1 = new Employee(1001, "Tom");
        Employee e2 = new Employee(1002, "Jerry");
        Employee[] arr1 = new Employee[]{e1, e2};
        Stream<Employee> stream2 = Arrays.stream(arr1);

        //通过Stream的of()
        Stream<Integer> stream3 = Stream.of(1, 2, 3, 4, 5, 6);
    }

    //中间操作
    @Test
    public void StreamAPIOperationExer(){
        //1.筛选与切片
        List<Employee> list = EmployeeData.getEmployees();

        //filter(Predicate p)--接收Lambda，从流中排除某些元素
        Stream<Employee> stream = list.stream();
        stream.filter(e -> e.getSalary() > 7000).forEach(System.out::println);
        //limit(n)--截断流，使其元素不超过给定数量
        list.stream().limit(3).forEach(System.out::println);
        //skip(n)--跳过元素，返回一个扔掉前n个元素的流
        list.stream().skip(3).forEach(System.out::println);
        //distinct()--筛选，通过流生成元素的hashCode()和equals()  去除重复的元素
        list.add(new Employee(1010, "刘强东", 40,  8000));
        list.add(new Employee(1010, "刘强东", 40,  8000));
        list.stream().distinct().forEach(System.out::println);
    }

    @Test
    public void testyingshe(){
        //map(Function f)--接收一个函数作为参数，将元素转化为其他形式或提取信息，该函数会被应用到每个元素上，并将其映射成一个新的元素
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
        list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);

        List<Employee> employees = EmployeeData.getEmployees();
        Stream<String> nameStream = employees.stream().map(Employee::getName);
        nameStream.filter(name -> name.length() > 3).forEach(System.out::println);
        //flatMap(Function f)--接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流。
        Stream<Stream<Character>> streamStream = list.stream().map(Java8NewProperties::fromStringToStream);

    }
    //将字符串中的多个字符构成的集合转换为对应的Stream的实例
    public static Stream<Character> fromStringToStream(String str){
        ArrayList<Character> list = new ArrayList<>();
        for (Character c :
                str.toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }

    @Test
    public void test4(){
        //sorted--自然排序
        List<Integer> list = Arrays.asList(12, 3, 21, 2, 32, 1, 1 ,2, 21);
        list.stream().sorted().forEach(System.out::println);
        //sorted(Comparator com)--定制排序
        List<Employee> employees = EmployeeData.getEmployees();
        employees.stream().sorted((e1, e2) -> {
            return Integer.compare(e1.getAge(), e2.getAge());
        }).forEach(System.out::println);
    }

    @Test
    public void testTerminal(){
        List<Employee> employees = EmployeeData.getEmployees();
        boolean allMatch = employees.stream().allMatch(e -> e.getAge() > 18);
        System.out.println(allMatch);
        boolean anyMatch = employees.stream().anyMatch(e -> e.getSalary() > 10000);
        System.out.println(anyMatch);
        boolean noneMatch = employees.stream().noneMatch(e -> e.getName() == "jack");
        Optional<Employee> first = employees.stream().findFirst();
        Optional<Employee> any = employees.parallelStream().findAny();


        employees.stream().filter(e -> e.getSalary() > 5000).count();
        //最大工资
        Stream<Double> salaryStream = employees.stream().map(e -> e.getSalary());
        Optional<Double> max = salaryStream.max(Double::compare);
        //最低工资
        Optional<Employee> min = employees.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        //forEach

    }
    @Test
    public void testStipulations(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 12, 4);
        list.stream().reduce(0,Integer::sum);
    }

    @Test
    public void testCollect(){
        List<Employee> employees = EmployeeData.getEmployees();
        List<Employee> employeeList = employees.stream().filter(e -> e.getAge() > 10).collect(Collectors.toList());
        employeeList.forEach(System.out::println);

    }




}
